home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 1 Issue 2 / PDCD-1 - Issue 02.iso / _utilities / utilities / 003 / motorola / Sources / c / symtab < prev    next >
Text File  |  1993-07-18  |  19KB  |  497 lines

  1. #include <string.h>
  2. #include <stdio.h>
  3.  
  4. #include "mselect.h"    /*external selection of microprocessor symbol table*/
  5. #include "proto.h"
  6. #include "as.h"
  7. #include "structs.h"
  8. #ifdef HC11
  9.         #include "table11.h"
  10. #else
  11.         #include "table5.h"
  12. #endif
  13. #include "extvars.h"
  14.  
  15. /*
  16.  * pseudo --- pseudo op processing
  17.  */
  18.  
  19. #define RMB     0               /* Reserve Memory Bytes         */
  20. #define FCB     1               /* Form Constant Bytes          */
  21. #define FDB     2               /* Form Double Bytes (words)    */
  22. #define FCC     3               /* Form Constant Characters     */
  23. #define ORG     4               /* Origin                       */
  24. #define EQU     5               /* Equate                       */
  25. #define ZMB     6               /* Zero memory bytes            */
  26. #define FILL    7               /* block fill constant bytes    */
  27. #define OPT     8               /* assembler option             */
  28. #define NULL_OP 9               /* null pseudo op               */
  29. #define PAGE    10              /* new page                     */
  30. #define INCLUDE 11              /* include <file> or "file" ver TER_2.0         */
  31. #define END     12              /* include <file> terminator ver TER_2.0        */
  32. #define IFD     13              /* if define <symbol> ver TER_2.0 */
  33. #define IFND    14              /* if not define <symbol> ver TER_2.0 */
  34. #define ELSE    15              /* else (for IF statements) ver TER_2.0 */
  35. #define ENDIF   16              /* endif (for IF statements) ver TER_2.0 */
  36. #define BSS     17              /* block storage segment (RAM) ver TER_2.09 */
  37. #define CODE    18              /* code segment ver TER_2.09 25 Jul 89 */
  38. #define DATA    19              /* data segment ver TER_2.09 25 Jul 89 */
  39. #define AUTO    20              /* data segment ver TER_2.09 25 Jul 89 */
  40.  
  41.  
  42. struct oper     pseudo[] = {
  43.         "=", PSEUDO, EQU, 0,    /* ver TER_2.09 25 Jul 89 */
  44.         "auto", PSEUDO, AUTO, 0,/* ver TER_2.09 25 Jul 89 */
  45.         "bss", PSEUDO, BSS, 0,  /* ver TER_2.09 25 Jul 89 */
  46.         "bsz", PSEUDO, ZMB, 0,
  47.         "code", PSEUDO, CODE, 0,/* ver TER_2.09 25 Jul 89 */
  48.         "data", PSEUDO, DATA, 0,/* ver TER_2.09 25 Jul 89 */
  49.         "else", PSEUDO, ELSE, 0,/* ver TER_2.0 6/17/89 */
  50.         "end", PSEUDO, END, 0,  /* ver TER_2.0 6/17/89 */
  51.         "endif", PSEUDO, ENDIF, 0,      /* ver TER_2.0 6/17/89 */
  52.         "equ", PSEUDO, EQU, 0,
  53.         "fcb", PSEUDO, FCB, 0,
  54.         "fcc", PSEUDO, FCC, 0,
  55.         "fdb", PSEUDO, FDB, 0,
  56.         "fill", PSEUDO, FILL, 0,
  57.         "ifd", PSEUDO, IFD, 0,  /* ver TER_2.0 6/17/89 */
  58.         "ifnd", PSEUDO, IFND, 0,/* ver TER_2.0 6/17/89 */
  59.         "include", PSEUDO, INCLUDE, 0,  /* ver TER_2.0 6/17/89 */
  60.         "nam", PSEUDO, NULL_OP, 0,
  61.         "name", PSEUDO, NULL_OP, 0,
  62.         "opt", PSEUDO, OPT, 0,
  63.         "org", PSEUDO, ORG, 0,
  64.         "pag", PSEUDO, PAGE, 0,
  65.         "page", PSEUDO, PAGE, 0,
  66.         "ram", PSEUDO, BSS, 0,  /* ver TER_2.09 25 Jul 89 */
  67.         "rmb", PSEUDO, RMB, 0,
  68.         "spc", PSEUDO, NULL_OP, 0,
  69.         "ttl", PSEUDO, NULL_OP, 0,
  70.         "zmb", PSEUDO, ZMB, 0
  71. };
  72.  
  73. /*
  74.  * do_pseudo --- do pseudo op processing
  75.  */
  76. void
  77. do_pseudo(int op)
  78. /* int op; which op */
  79. {
  80.         char            fccdelim;
  81.         int             fill;
  82.         int             c;      /* test variable  ver TER_2.0 6/18/89 */
  83.         char           *savept; /* savept is pointer to string save */
  84.         FILE           *FdTemp; /* ver TER_2.0 6/17/89 */
  85.         /*
  86.          * void    pouterror(), NewPage(), IfMachine();
  87.          *//* rel TER_2.0 6/18/89 */
  88.         /* void    PC_Exchange();  *//* ver TER_2.09 25 Jul 89 */
  89.  
  90.         if (op != EQU && *Label)
  91.                 install(Label, Pc);
  92.  
  93.         P_force++;
  94.  
  95. #ifdef DEBUG3
  96.         printf("%s, line no. ", Argv[Cfn]);     /* current file name */
  97.         printf("%d: ", Line_num);       /* current line number */
  98.         printf(" Pseudo Op=%u\n", op);
  99. #endif
  100.  
  101.         switch (op) {
  102.         case RMB:               /* reserve memory bytes */
  103.                 if (eval()) {
  104.                         Pc += Result;
  105.                         f_record();     /* flush out bytes */
  106.                 } else
  107.                         error("Undefined Operand during Pass One");
  108.                 break;
  109.         case ZMB:               /* zero memory bytes */
  110.                 if (eval())
  111.                         while (Result--)
  112.                                 emit(0);
  113.                 else
  114.                         error("Undefined Operand during Pass One");
  115.                 break;
  116.         case FILL:              /* fill memory with constant */
  117.                 eval();
  118.                 fill = Result;
  119.                 if (*Optr++ != ',')
  120.                         error("Bad fill");
  121.                 else {
  122.                         Optr = skip_white(Optr);
  123.                         eval();
  124.                         while (Result--)
  125.                                 emit(fill);
  126.                 }
  127.                 break;
  128.         case FCB:               /* form constant byte(s) */
  129.                 do {
  130.                         Optr = skip_white(Optr);
  131.                         eval();
  132.                         if (Result > 0xFF) {
  133.                                 if (!Force_byte)
  134.                                         warn("Value truncated");
  135.                                 Result = lobyte(Result);
  136.                         }
  137.                         emit(Result);
  138.                 } while (*Optr++ == ',');
  139.                 break;
  140.         case FDB:               /* form double byte(s) */
  141.                 do {
  142.                         Optr = skip_white(Optr);
  143.                         eval();
  144.                         eword(Result);
  145.                 } while (*Optr++ == ',');
  146.                 break;
  147.         case FCC:               /* form constant characters */
  148.                 if (*Operand == EOS)
  149.                         break;
  150. /*                Optr++;*/
  151.                 fccdelim = *Optr++;
  152.                 if ((fccdelim != SQUOT) && (fccdelim != DQUOT))
  153.                         {error("Missing Delimiter - \' or \" expected");
  154.                           break;}
  155. /*              putchar ( fccdelim );*/
  156.                 while (*Optr != EOS && *Optr != fccdelim)
  157.                         emit(*Optr++);
  158.                 if (*Optr == fccdelim)
  159.                         {Optr++;}
  160.                 else
  161.                         {error("Missing Delimiter");}
  162.                 break;
  163.         case ORG:               /* origin */
  164.                 if (eval()) {
  165.                         Old_pc = Pc = Result;
  166.                         f_record();     /* flush out any bytes */
  167.                 } else
  168.                         error("Undefined Operand during Pass One");
  169.                 break;
  170.         case EQU:               /* equate */
  171.                 if (*Label == EOS) {
  172.                         error("EQU requires label");
  173.                         break;
  174.                 }
  175.                 if (eval()) {
  176.                         install(Label, Result);
  177.                         Old_pc = Result;        /* override normal */
  178.                 } else
  179.                         error("Undefined Operand during Pass One");
  180.                 break;
  181.         case OPT:               /* assembler option */
  182.                 P_force = 0;
  183.                 if (head(Operand, "l"))
  184.                         Lflag = 1;
  185.                 else if (head(Operand, "nol"))
  186.                         Lflag = 0;
  187.                 else if (head(Operand, "c")) {
  188.                         Cflag = 1;
  189.                         Ctotal = 0;
  190.                 } else if (head(Operand, "noc"))
  191.                         Cflag = 0;
  192.                 else if (head(Operand, "contc")) {
  193.                         Cflag = 1;
  194.                 } else if (head(Operand, "s"))
  195.                         Sflag = 1;
  196.                 else if (head(Operand, "cre"))
  197.                         CREflag = 1;
  198.                 else if (head(Operand, "p50"))  /* turn on page flag */
  199.                         Pflag50 = 1;    /* ver (TER) 2.02 19 Jun 89 */
  200.                 else if (head(Operand, "crlf")) /* add <CR> <LF> to */
  201.                         CRflag = 1;     /* S record ver TER_2.08 */
  202.                 else if (head(Operand, "nnf"))  /* no extra line no. */
  203.                         nfFlag = 0;     /* w include files ver TER_2.08 */
  204.                 else
  205.                         error("Unrecognized OPT");
  206.                 break;
  207.         case PAGE:              /* go to a new page */
  208.                 P_force = 0;
  209.                 N_page = 1;
  210.                 if (Pass == 2)
  211.                         if (Lflag)
  212.                                 NewPage();
  213.                 break;
  214.         case NULL_OP:           /* ignored psuedo ops */
  215.                 P_force = 0;
  216.                 break;
  217.         case INCLUDE:           /* case INCLUDE added ver TER_2.0 6/17/89 */
  218.                 P_force = 0;    /* no PC in printed output */
  219.                 if ((c = FNameGet(InclFName)) == 0)
  220.                         error("Improper INCLUDE statement");
  221.                 else {
  222.                         if (FdCount > MAXINCFILES)
  223.                                 error("too many INCLUDE files");
  224.                         else {
  225.                                 if ((FdTemp = fopen(InclFName, "r")) == 0) {
  226.                                         warn(strcat("can't open INCLUDE file ", InclFName));
  227.                                 } else {
  228.                                         if ((savept = strsave(InclFName)) == 0)
  229.                                                 error("out of memory for INCLUDE file name");
  230.                                         else {
  231.                                                 InclFiles[FdCount].fp = Fd;     /* save current fp */
  232.                                                 if (nfFlag) {
  233.                                                         InclFiles[FdCount].line_num = Line_num;
  234.                                                         /*
  235.                                                          * save current line
  236.                                                          * count
  237.                                                          */
  238.                                                         Line_num = 0;   /* reset for new file */
  239.                                                 }
  240.                                                 InclFiles[FdCount].name = Argv[Cfn];
  241.                                                 /*
  242.                                                  * save pointer to current
  243.                                                  * name
  244.                                                  */
  245.                                                 Argv[Cfn] = savept;
  246.                                                 /*
  247.                                                  * now replace pointer to
  248.                                                  * current name with pointer
  249.                                                  * to name of Include file
  250.                                                  */
  251.                                                 Fd = FdTemp;    /* now replace current
  252.                                                                  * file with INCLUDE fp */
  253.                                                 FdCount++;      /* and increment "stack" */
  254. #ifdef DEBUG2
  255.                                                 printf("pseudo INCLUDE: FdCount=%d\n", FdCount);
  256.                                                 printf("  new input file pointer=%d\n", Fd);
  257.                                                 printf("  new file name=%s\n", Argv[Cfn]);
  258. #endif
  259.                                         }
  260.                                 }
  261.                         }
  262.                 }
  263.                 break;
  264.         case END:
  265.                 P_force = 0;
  266.                 if (FdCount > 0) {      /* skip END statements in files
  267.                                          * received from CLI arguments */
  268.                         fclose(Fd);     /* close file from this level nest */
  269.                         FdCount--;      /* "pop stack" */
  270.                         Fd = InclFiles[FdCount].fp;     /* restore fp from
  271.                                                          * nested stack */
  272.                         if (nfFlag)
  273.                                 Line_num = InclFiles[FdCount].line_num;
  274.                         Argv[Cfn] = InclFiles[FdCount].name;
  275.                         /* restore file name pointer */
  276. #ifdef DEBUG2
  277.                         printf("pseudo END: FdCount=%d\n", FdCount);
  278.                         printf("  new input file pointer=%d\n", Fd);
  279.                         printf("  new file name=%s\n", Argv[Cfn]);
  280. #endif
  281.                 }
  282.                 break;
  283.         case IFD:
  284. #ifdef DEBUG3
  285.                 printf("case IFD: in pseudo\n");
  286. #endif
  287.                 P_force = 0;
  288.                 c = eval_ifd();
  289.                 IfMachine(c);
  290.                 break;
  291.         case IFND:
  292.                 P_force = 0;
  293.                 c = eval_ifnd();
  294.                 IfMachine(c);
  295.                 break;
  296.         case ELSE:
  297.                 P_force = 0;
  298.                 IfMachine(IF_ELSE);
  299.                 break;
  300.         case ENDIF:
  301.                 P_force = 0;
  302.                 IfMachine(IF_ENDIF);
  303.                 break;
  304.         case CODE:              /* CODE,DATA,BSS,AUTO ver TER_2.09 */
  305.                 PC_Exchange(0);
  306.                 break;
  307.         case DATA:
  308.                 PC_Exchange(1);
  309.                 break;
  310.         case BSS:
  311.                 PC_Exchange(2);
  312.                 break;
  313.         case AUTO:
  314.                 PC_Exchange(3);
  315.                 break;
  316.         default:
  317.                 fatal("Pseudo error");
  318.                 break;
  319.         }
  320. }
  321.  
  322.  
  323. /*
  324.  * PC_Exchange --- Save current PC and recover requested one added ver
  325.  * TER_2.09
  326.  */
  327. void
  328. PC_Exchange(int PC_ptr_new)
  329. /* int PC_ptr_new; request 0=CODE,1=DATA,2=BSS */
  330. {
  331.         P_force = 0;            /* no PC in output cuz wrong first time (?) */
  332.         PC_Save[PC_ptr] = Pc;   /* save current PC */
  333.         PC_ptr = PC_ptr_new;    /* remember which one we're using */
  334.         Old_pc = Pc = PC_Save[PC_ptr];  /* recover the one requested */
  335.         f_record();             /* flush out any bytes, this is really an ORG */
  336. }
  337.  
  338. /* pseudo module ends here */
  339.  
  340.  
  341.  
  342. /*
  343.  * install --- add a symbol to the table
  344.  */
  345. int
  346. install(char *str, int val)
  347. {
  348.         struct link    *lp;
  349.         struct nlist   *np, *p, *backp;
  350.         int             i;
  351.         /* char *LastChar();    *//* ver TER_2.0 */
  352.  
  353.         if (!alpha(*str)) {
  354.                 error("Illegal Symbol Name");
  355.                 return (NO);
  356.         }
  357.         if ((np = lookup(str)) != NULL) {
  358.                 if (*LastChar(str) == '@') {    /* redefinable symbol  ver
  359.                                                  * TER_2.0 */
  360.                         np->def = val;  /* redefined */
  361.                         return (YES);
  362.                 }
  363.                 if (Pass == 2) {
  364.                         np->def2 = 2;   /* defined for this pass=Pass  ver
  365.                                          * TER_2.0 */
  366.                         if (np->def == val)
  367.                                 return (YES);
  368.                         else {
  369.                                 error("Phasing Error");
  370.                                 return (NO);
  371.                         }
  372.                 }
  373.                 error("Symbol Redefined");
  374.                 return (NO);
  375.         }
  376.         /* enter new symbol */
  377. #ifdef DEBUG
  378.         printf("Installing %s as %d\n", str, val);
  379. #endif
  380.         np = (struct nlist *) alloc(sizeof(struct nlist));
  381.         if (np == (struct nlist *) ERR) {
  382.                 error("Symbol table full");
  383.                 return (NO);
  384.         }
  385.         np->name = alloc(strlen(str) + 1);
  386.         if (np->name == (char *) ERR) {
  387.                 error("Symbol table full");
  388.                 return (NO);
  389.         }
  390.         strcpy(np->name, str);
  391.         np->def = val;
  392.         np->def2 = 1;           /* defined for this pass=Pass  ver TER_2.0 */
  393.         np->Lnext = NULL;
  394.         np->Rnext = NULL;
  395.         lp = (struct link *) alloc(sizeof(struct link));
  396.         np->L_list = lp;
  397.         lp->L_num = Line_num;
  398.         lp->next = NULL;
  399.         p = root;
  400.         backp = NULL;
  401.         while (p != NULL) {
  402.                 backp = p;
  403.                 i = strcmp(str, p->name);
  404.                 if (i < 0)
  405.                         p = p->Lnext;
  406.                 else
  407.                         p = p->Rnext;
  408.         }
  409.         if (backp == NULL)
  410.                 root = np;
  411.         else if (strcmp(str, backp->name) < 0)
  412.                 backp->Lnext = np;
  413.         else
  414.                 backp->Rnext = np;
  415.         return (YES);
  416. }
  417.  
  418. /*
  419.  * lookup --- find string in symbol table
  420.  */
  421. struct nlist   *
  422. lookup(char *name)
  423. {
  424.         struct nlist   *np;
  425.         int             i;
  426.         char           *c;      /* ver TER_2.0 */
  427.  
  428.         c = name;               /* copy symbol pointer */
  429.         while (alphan(*c))      /* search for end of symbol */
  430.                 c++;            /* next char */
  431.         *c = EOS;               /* disconnect anything after for good compare */
  432.         /* end of mods for ver TER_2.0 */
  433.  
  434.         np = root;              /* and now go on and look for symbol */
  435.         while (np != NULL) {
  436.                 i = strcmp(name, np->name);
  437.                 if (i == 0) {
  438.                         Last_sym = np->def;
  439.                         return (np);
  440.                 } else if (i < 0)
  441.                         np = np->Lnext;
  442.                 else
  443.                         np = np->Rnext;
  444.         }
  445.         Last_sym = 0;
  446.         /*
  447.          * if (Pass == 2) error ("symbol Undefined on pass 2");
  448.          */
  449.         /* commented out ver TER_2.0 2 Jul 89 */
  450.         /* function used in IFD */
  451.         return (NULL);
  452. }
  453.  
  454.  
  455. #define NMNE (sizeof(table)/ sizeof(struct oper))
  456. #define NPSE (sizeof(pseudo)/ sizeof(struct oper))
  457. /*
  458.  * mne_look --- mnemonic lookup
  459.  * 
  460.  * Return pointer to an oper structure if found. Searches both the machine
  461.  * mnemonic table and the pseudo table.
  462.  */
  463. struct oper    *
  464. mne_look(char *str)
  465. {
  466.         struct oper    *low, *high, *mid;
  467.         int             cond;
  468.  
  469.         /* Search machine mnemonics first */
  470.         low = &table[0];
  471.         high = &table[NMNE - 1];
  472.         while (low <= high) {
  473.                 mid = low + (high - low) / 2;
  474.                 if ((cond = strcmp(str, mid->mnemonic)) < 0)
  475.                         high = mid - 1;
  476.                 else if (cond > 0)
  477.                         low = mid + 1;
  478.                 else
  479.                         return (mid);
  480.         }
  481.  
  482.         /* Check for pseudo ops */
  483.         low = &pseudo[0];
  484.         high = &pseudo[NPSE - 1];
  485.         while (low <= high) {
  486.                 mid = low + (high - low) / 2;
  487.                 if ((cond = strcmp(str, mid->mnemonic)) < 0)
  488.                         high = mid - 1;
  489.                 else if (cond > 0)
  490.                         low = mid + 1;
  491.                 else
  492.                         return (mid);
  493.         }
  494.  
  495.         return (NULL);
  496. }
  497.